package com.junzhiit.nengji.shop.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bainaeco.framework.util.DateUtil;
import com.bainaeco.framework.util.serializer.Format;
import com.junzhiit.nengji.bo.BookingBO;
import com.junzhiit.nengji.dao.BookingDAO;
import com.junzhiit.nengji.dao.ShopClientDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.TableTypeDAO;
import com.junzhiit.nengji.dao.UserDAO;
import com.junzhiit.nengji.dao.WechatConfigDAO;
import com.junzhiit.nengji.dao.cache.WechatConfigCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Booking;
import com.junzhiit.nengji.model.Shop;
import com.junzhiit.nengji.model.ShopClient;
import com.junzhiit.nengji.model.User;
import com.junzhiit.nengji.model.WechatConfig;
import com.junzhiit.nengji.model.enums.BookingStatus;
import com.junzhiit.nengji.model.enums.PayWay;
import com.junzhiit.nengji.shop.service.BookingService;
import com.junzhiit.nengji.shop.web.exception.BalanceInsufficientException;
import com.junzhiit.nengji.shop.web.exception.NotFoundException;
import com.junzhiit.nengji.shop.web.exception.UserNotFoundException;
import com.junzhiit.nengji.shop.web.exception.WechatConfigAddException;
import com.junzhiit.nengji.shop.web.util.Constants;
import com.junzhiit.nengji.shop.web.util.OrderNumberUtils;
import com.junzhiit.nengji.shop.web.util.RequestUtil;
import com.junzhiit.nengji.shop.web.util.wechat.WeChatUtils;
import com.junzhiit.nengji.shop.web.util.wechat.bean.OrderInfo;
import com.junzhiit.nengji.shop.web.util.wechat.bean.PayParam;
import com.junzhiit.nengji.shop.web.vo.BookingEditVO;
import com.junzhiit.nengji.shop.web.vo.BookingSearchVO;
import com.junzhiit.nengji.shop.web.vo.BookingVO;
import com.junzhiit.nengji.shop.web.vo.ResultVO;

@Service
public class BookingServiceImpl extends BaseServiceImpl implements BookingService {

	@Autowired
	private BookingDAO bookingDAO;

	@Autowired
	private TableTypeDAO tableTypeDAO;

	@Autowired
	private WechatConfigDAO wechatConfigDAO;

	@Autowired
	private WechatConfigCacheDAO wechatConfigCacheDAO;
	
	@Autowired
	private UserDAO userDAO;
	
	@Autowired
	private ShopClientDAO shopClientDAO;
	
	@Autowired
	private ShopDAO shopDAO;
	
	private final String WECHAT_BODY_KEY = "乐鸽订单";

	@Override
	public ResultVO findTableTypeAll(String shopId) {
		ResultVO result = new ResultVO();
		result.setData(tableTypeDAO.findAll(shopId));
		return result;
	}

	@Override
	public ResultVO add(HttpServletRequest request,BookingVO bookingVO) {
		ResultVO result = new ResultVO();
		Map<String, Object> map = new HashMap<String, Object>();
		User user = userDAO.query(bookingVO.getUserId());
		if (user == null) {
			throw new UserNotFoundException("用户没找到！");
		}
		int surplus = tableTypeDAO.surplusTable(bookingVO.getTableTypeId());
		if(surplus<=0){
			map.put("surplus", surplus);
			result.setData(map);
			return result;
		}
		
		String bookingNumber = OrderNumberUtils.getOrderlNumber();
		Booking booking =new Booking();
		BeanUtils.copyProperties(bookingVO,booking);
		booking.setBookingNumber(bookingNumber);
		Long endTime = bookingVO.getChooseTime().getTime()+(bookingVO.getValidTime()*1000);
		booking.setEndTime(DateUtil.getTime(endTime));
		
		if(bookingVO.getPayWay() == PayWay.WECHAT.toIntValue()){
			booking.setStatus(BookingStatus.PAYMENT.toIntValue());
			booking = bookingDAO.insert(booking);
			// 微信支付
			OrderInfo orderInfo = new OrderInfo();
			orderInfo.setAttach(Constants.WECHAT_ATTACH_FOR_BOOKING);
			orderInfo.setOutTradeNo(bookingNumber);
			orderInfo.setBody(WECHAT_BODY_KEY + "-" + bookingNumber);
			orderInfo.setTotalFee(Math.round(booking.getMoney() * 100));
			orderInfo.setSpbillCreateIp(RequestUtil.getRealIp(request));
			orderInfo.setOpenId(user.getOpenId());
			orderInfo.setTradeType(bookingVO.getTradeType());

			String wechatKey = DIYKey.getWechatCodeKey(bookingVO.getWcId());
			WechatConfig wechatConfig = wechatConfigCacheDAO.getHash(wechatKey, WechatConfig.class);
			if (wechatConfig == null) {
				wechatConfig = wechatConfigDAO.getWechatConfigByWcId(bookingVO.getWcId());
				boolean is = wechatConfigCacheDAO.addHash(wechatKey, wechatConfig);
				if (!is) {
					throw new WechatConfigAddException("找不到微信配置");
				}
			}

			PayParam payParam = WeChatUtils.getPayParam(orderInfo, wechatConfig);
			
			map.put("patParam", payParam);
		} else if (bookingVO.getPayWay() == PayWay.MEMBER.toIntValue()) {
			Shop shop = shopDAO.query(bookingVO.getShopId());
			String csId = null;
			if(StringUtils.isNotBlank(shop.getChainId())){
				csId = 	shop.getChainId();
			}else{
				csId = shop.getId();
			}
			// 使用会员卡支付
			ShopClient shopClient = shopClientDAO.findClientByUserId(bookingVO.getUserId(), csId);
			if(shopClient!=null && shopClient.getBalance() > bookingVO.getMoney()){
				Double balance = Format.decimal(shopClient.getBalance() - bookingVO.getMoney());
				shopClient.setBalance(balance);
				boolean boo = shopClientDAO.update(shopClient);
				if (boo) {
					booking.setPayTime(new Date());
					booking.setStatus(BookingStatus.CONFIRM.toIntValue());
					booking = bookingDAO.insert(booking);
				}
			}else {
				throw new BalanceInsufficientException("余额不足");
			}
		}
		map.put("bookingNumber", bookingNumber);
		map.put("bookingId", booking.getId());
		map.put("surplus", surplus);
		result.setData(map);
		return result;
	}

	@Override
	public ResultVO update(BookingEditVO bookingEditVO) {
		ResultVO result = new ResultVO();
		Booking booking =  bookingDAO.query(bookingEditVO.getId());
		if(booking == null){
			throw new NotFoundException("update: booking not found.");
		}
		booking.setStatus(bookingEditVO.getStatus());
		boolean boo = bookingDAO.update(booking);
		result.setData(boo);
		return result;
	}

	@Override
	public ResultVO findAll(BookingSearchVO bookingSearchVO) {
		ResultVO result = new ResultVO();
		Booking booking = new Booking();
		BeanUtils.copyProperties(bookingSearchVO,booking);
		List<BookingBO> list = bookingDAO.findAll(booking,bookingSearchVO.getPageNumber(),bookingSearchVO.getMaxPageRow());
		result.setData(list);
		return result;
	}

}
